﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

//class Time
//{
//public:
//	Time()
//	{
//		_hour = 0;
//		_minute = 0;
//		_second = 0;
//	}
//
//private:
//	int _hour;
//	int _minute;
//	int _second;
//};
//
//class Date
//{
//public:
//	////自己定义的无参构造函数
//	//Date()
//	//{}
//
//	////自己定义的但参构造函数
//	//Date(int year, int month, int day)
//	//{
//	//	_year = year;
//	//	_month = month;
//	//	_day = day;
//	//}
//
//	////自己定义的全缺省构造函数,语法没有问题,但是调用无参构造函数是会发生歧义
//	////编译器会报错
//	//Date(int year = 1, int month = 1, int day = 1)
//	//{
//	//	_year = year;
//	//	_month = month;
//	//	_day = day;
//	//}
//
//private:
//	int _year;
//	int _month;
//	int _day;
//
//	Time _t;//编译器自动生成的构造函数只会初始化自定义类型,初始的方法就是调用它的默认构造函数,
//	//默认构造函数有三个,无参构造函数,全缺省构造函数,和编译器自动生成的构造函数,简单理解不含参的构造函数
//	
//	//1.如果它有默认构造则不会报错,包括编译器自动生成的.
//	//2.如果它没有默认构造函数则会报错,(它如果自己定义了构造函数,编译器就不生成构造函数了)
//};
//
//int main()
//{
//	////Date d1;//报错,调用无参构造,但是全缺省和无参只能有一个
//	//Date d2(2015, 1, 1);
//	//Date d3();//注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数的声明
//
//	Date d1;
//	return 0;
//}
//
////但是编译器自动生成构造函数,只初始化内置类型,C++针对内置类型成员不初始化的缺陷,又打了补丁,
////即:内置类型成员变量在类中声明的时候可以给默认值
////总结一下:如果类中只有内置类型,自己写构造函数初始化
////如果类中只有自定义类型,使用编译器默认构造函数
////如果既有内置类型又有自定义类型,就给内置成员变量默认值,使用编译器默认构造函数


//typedef int DataType;
//
//class Stack
//{
//public:
//	Stack(size_t capacity = 3)
//	{
//		_array = (DataType*)malloc(sizeof(DataType) * capacity);
//		if (NULL == _array)
//		{
//			perror("malloc申请空间失败!!!");
//			return;
//		}
//		_capacity = capacity;
//		_size = 0;
//	}
//	void Push(DataType data)
//	{
//		// CheckCapacity();
//		_array[_size] = data;
//		_size++;
//	}
//	// 其他方法...
//	//编译器自动生成的析构函数,内置类型不做处理,自定义类型去调用它的析构
//	~Stack()
//	{
//		if (_array)
//		{
//			free(_array);//这里如果使用编译器默认析构函数,会内存泄漏
//			_array = NULL;
//			_capacity = 0;
//			_size = 0;
//
//		}
//	}
//private:
//	DataType* _array;
//	int _capacity;
//	int _size;
//};
//
////对象生命周期结束时,C++编译器系统自动调用析构函数
//void TestStack()
//{
//	Stack s;
//	s.Push(1);
//	s.Push(2);
//}
//
////编译器生成的默认析构函数,对自定类型成员调用它的析构函数,内置类型不做处理(可能导致内存泄漏)
////所以,有资源需要清理,就需要写析构函数
////没有资源清理,或则内置类型成员无资源清理,剩下的都是自定类型不需要写析构函数
//class Time
//{
//public:
//	~Time()
//	{
//		cout << "~Time()" << endl;
//	}
//private:
//	int _hour;
//	int _minute;
//	int _second;
//};
//class Date
//{
//private:
//	// 基本类型(内置类型)
//	int _year = 1970;
//	int _month = 1;
//	int _day = 1;
//	// 自定义类型
//	Time _t;
//};
//int main()
//{
//	Date d;
//	return 0;
//}
////对于这段代码,先分析构造函数,创建Date d对象时,调用其构造函数,没有则编译器自动构造函数,对基本类型不做处理
////自定义类型调用其默认构造函数,初始化_t,调用其默认构造函数,没有则编译器自动生成,对基本类型不处理,故_hour,
////_minute,_second都为随机值
//
////析构函数,程序结束时自动调用其析构函数,没有则编译器自动生成,对基本类型不处理,自定义类型调用其析构函数,
////故调用_t的析构函数,输出了"~time"

//class Date
//{
//public:
//	Date(int year, int month, int day)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//
//	void Print()
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//private:
//	// 给缺省值
//	int _year = 1;
//	int _month = 1;
//	int _day = 1;
//};
//
//
////比如说我们调用内置类型的时候,传值调用都是一份临时拷贝,
////这里传对象也是一样
////但是,如果我们传值调用拷贝函数,编译器会直接报错,因为会引发无穷递归调用
////void func(Date d)
//void func(Date& d)
//{
//	d.Print();
//}
//
//
//class Date
//{
//public:
//	Date(int year = 1900, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	// Date(const Date& d)   // 正确写法
//	Date(const Date& d)   // 错误写法：编译报错，会引发无穷递归
//	{
//		_year = d._year;
//		_month = d._month;
//		_day = d._day;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	Date d1;
//	Date d2(d1);
//	return 0;
//}

// 这里会发现下面的程序会崩溃掉？这里就需要我们以后讲的深拷贝去解决。
//typedef int DataType;
//class Stack
//{
//public:
//	Stack(size_t capacity = 10)
//	{
//		_array = (DataType*)malloc(capacity * sizeof(DataType));
//		if (nullptr == _array)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}//注意：类中如果没有涉及资源申请时，拷贝构造函数是否写都可以；一旦涉及到资源申请
//			//时，则拷贝构造函数是一定要写的，否则就是浅拷贝。
//			_size = 0;
//		_capacity = capacity;
//	}
//	void Push(const DataType& data)
//	{
//		// CheckCapacity();
//		_array[_size] = data;
//		_size++;
//	}
//	~Stack()
//	{
//		if (_array)
//		{
//			free(_array);
//			_array = nullptr;
//			_capacity = 0;
//			_size = 0;
//		}
//	}
//private:
//	DataType* _array;
//	size_t _size;
//	size_t _capacity;
//};
//int main()
//{
//	Stack s1;
//	s1.Push(1);
//	s1.Push(2);
//	s1.Push(3);
//	s1.Push(4);
//	Stack s2(s1);
//	return 0;
//}

class Date
{
public:
	Date(int year, int minute, int day)
	{
		cout << "Date(int,int,int):" << this << endl;
	}
	Date(const Date& d)
	{
		cout << "Date(const Date& d):" << this << endl;
	}
	~Date()
	{
		cout << "~Date():" << this << endl;
	}
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};
Date Test(Date d)
{
	Date temp(d);
	return temp;
}
int main()
{
	Date d1(2022, 1, 13);
	Test(d1);
	return 0;
}

Stack(const Stack& st)
	{
		_array = (DataType*)malloc(sizeof(DataType) * st._capacity);
		if (NULL == _array)
		{
			perror("malloc申请空间失败!!!");
			return;
		}

		memcpy(_array, st._array, sizeof(DataType) * st._size);

		_size = st._size;
		_capacity = st._capacity;
	}